package org.coody.finger.util;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.UnsupportedEncodingException;
import java.net.URLDecoder;
import java.security.MessageDigest;
import java.util.ArrayList;
import java.util.List;

import com.alibaba.fastjson.JSON;

public class FileUtil {

	public static String getMD5(File file) {
		FileInputStream fis = null;
		try {
			MessageDigest md = MessageDigest.getInstance("sha-256");
			fis = new FileInputStream(file);
			byte[] buffer = new byte[1024];
			int length = -1;
			while ((length = fis.read(buffer)) != -1) {
				md.update(buffer, 0, length);
			}
			return bytesToString(md.digest());
		} catch (Exception ex) {
			ex.printStackTrace();
			return null;
		} finally {
			try {
				if (fis != null) {
					fis.close();
				}
			} catch (IOException localIOException2) {
			}
		}
	}

	public static void writeFile(String path, byte[] content) {
		try {
			FileOutputStream fos = new FileOutputStream(path);

			fos.write(content);
			fos.close();
		} catch (Exception localException) {
		}
	}

	public static String getSHA(File file) {
		FileInputStream fis = null;
		try {
			MessageDigest md = MessageDigest.getInstance("SHA");
			fis = new FileInputStream(file);
			byte[] buffer = new byte[8192];
			int length = -1;
			while ((length = fis.read(buffer)) != -1) {
				md.update(buffer, 0, length);
			}
			return bytesToString(md.digest());
		} catch (Exception ex) {
			return null;
		} finally {
			try {
				fis.close();
			} catch (IOException localIOException2) {
			}
		}
	}

	@SuppressWarnings("resource")
	public static byte[] readFileByte(String path) {
		try {
			File file = new File(URLDecoder.decode(path, "UTF-8"));
			if (!file.exists()) {
				return null;
			}
			long fileSize = file.length();
			if (fileSize > 2147483647L) {
				return null;
			}
			FileInputStream fi = new FileInputStream(file);
			byte[] buffer = new byte[(int) fileSize];
			int offset = 0;
			int numRead = 0;
			while ((offset < buffer.length) && ((numRead = fi.read(buffer, offset, buffer.length - offset)) >= 0)) {
				offset += numRead;
			}
			if (offset != buffer.length) {
				throw new IOException("Could not completely read file " + file.getName());
			}
			fi.close();
			return buffer;
		} catch (Exception e) {
		}
		return null;
	}

	public static List<File> getFiles(String realpath) {
		List<File> files = new ArrayList<File>();
		try {
			File realFile = new File(URLDecoder.decode(realpath, "UTF-8"));
			if (realFile.isDirectory()) {
				File[] subfiles = realFile.listFiles();
				for (File file : subfiles) {
					try {
						if (file.isDirectory()) {
							files.addAll(getFiles(file.getAbsolutePath()));
						}
					} catch (Exception localException) {
					} 
					files.add(file);
				}
			}
		} catch (Exception e) {
		}
		return files;
	}

	public static String bytesToString(byte[] bytes) throws UnsupportedEncodingException {
		 StringBuffer sb = new StringBuffer(bytes.length);
	        String temp = null;
	        for (int i = 0;i< bytes.length;i++){
	            temp = Integer.toHexString(0xFF & bytes[i]);
	            if (temp.length() <2){
	                sb.append(0);
	            }
	            sb.append(temp);
	        }
	        return sb.toString();
	}

	public static String formatUrl(String path) {
		while (path.contains("\\")) {
			path = path.replace("\\", "/");
		}
		while (path.contains("//")) {
			path = path.replace("//", "/");
		}
		if (path.endsWith("/")) {
			path = path.substring(0, path.length() - 1);
		}
		return path;
	}

	public static boolean delete(String fileName) {
		File file = new File(fileName);
		if (!file.exists()) {
			return false;
		}
		if (file.isFile()) {
			return deleteFile(fileName);
		}
		return deleteDirectory(fileName);
	}

	public static boolean deleteFile(String fileName) {
		File file = new File(fileName);
		if ((file.exists()) && (file.isFile())) {
			if (file.delete()) {
				return true;
			}
			return false;
		}
		return false;
	}

	public static boolean deleteDirectory(String dir) {
		if (!dir.endsWith(File.separator)) {
			dir = dir + File.separator;
		}
		File dirFile = new File(dir);
		if ((!dirFile.exists()) || (!dirFile.isDirectory())) {
			return false;
		}
		boolean flag = true;

		File[] files = dirFile.listFiles();
		for (int i = 0; i < files.length; i++) {
			if (files[i].isFile()) {
				flag = deleteFile(files[i].getAbsolutePath());
				if (!flag) {
					break;
				}
			} else if (files[i].isDirectory()) {
				flag = deleteDirectory(files[i].getAbsolutePath());
				if (!flag) {
					break;
				}
			}
		}
		if (!flag) {
			return false;
		}
		if (dirFile.delete()) {
			return true;
		}
		return false;
	}

	public static void write(String path, String context) {
		write(path, context, "utf-8");
	}

	public static void write(String path, String context, String encode) {
		OutputStream pt = null;
		try {
			pt = new FileOutputStream(URLDecoder.decode(path, "UTF-8"));
			pt.write(context.getBytes(encode));
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				pt.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void writeAppend(String path, String context) {
		writeAppend(path, context, "utf-8");
	}

	public static void makeFileDir(String path) {
		while (path.contains("\\")) {
			path = path.replace("\\", "/");
		}
		while (path.contains("//")) {
			path = path.replace("//", "/");
		}
		int lastTag = path.lastIndexOf('/');
		if (lastTag == -1) {
			return;
		}
		path = path.substring(0, lastTag);
		if (!new File(path).exists()) {
			new File(path).mkdirs();
		}
	}

	public static void writeAppend(String path, String context, String encode) {
		BufferedWriter out = null;
		try {
			makeFileDir(path);
			out = new BufferedWriter(
					new OutputStreamWriter(new FileOutputStream(URLDecoder.decode(path, "UTF-8"), true)));
			out.write(context);
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			try {
				if (out != null) {
					out.close();
				}
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}

	public static void writeAppendLine(String path, String context) {
		writeAppendLine(path, context, "utf-8");
	}

	public static void writeAppendLine(String path, String context, String encode) {
		writeAppend(path, context + "\r\n", encode);
	}

	public static String readFile(String path) {
		return readFile(path, "utf-8");
	}

	public static String readFile(String path, String encode) {
		InputStreamReader read = null;
		FileInputStream in = null;
		BufferedReader bufferedReader = null;
		try {

			File file = new File(URLDecoder.decode(path, "UTF-8"));
			if (file.isFile() && file.exists()) { // 判断文件是否存在
				in = new FileInputStream(file);
				read = new InputStreamReader(in, encode);// 考虑到编码格式
				bufferedReader = new BufferedReader(read);
				StringBuilder sb = new StringBuilder();
				String line = null;
				while ((line = bufferedReader.readLine()) != null) {
					sb.append(line).append("\r\n");
				}
				return sb.toString();
			}
		} catch (Exception e) {
		} finally {
			try {
				bufferedReader.close();
				read.close();
				in.close();
			} catch (Exception e) {
			}
		}
		return null;
	}

	public static void createFileDir(String fileName) {
		fileName = formatUrl(fileName);
		String[] tabs = fileName.split("/");
		String currDir = "";
		for (int i = 0; i < tabs.length - 1; i++) {
			currDir = currDir + tabs[i] + "/";
			if (!new File(currDir).exists()) {
				new File(currDir).mkdirs();
			}
		}
	}

	public static void main(String[] args) {
		List<File> files=getFiles("D:/JAVA/WorkSpace/finger/target/classes/org/coody/finger");
		System.out.println(JSON.toJSONString(files));
	}
}
